package pro.shushi.pamirs.hr.core.manager.auth;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import pro.shushi.pamirs.boot.base.enmu.ActionTypeEnum;
import pro.shushi.pamirs.boot.base.model.*;
import pro.shushi.pamirs.boot.base.ux.cache.api.ActionCacheApi;
import pro.shushi.pamirs.boot.base.ux.cache.api.ModelActionsCacheApi;
import pro.shushi.pamirs.hr.api.enums.HrSimpleExpEnum;
import pro.shushi.pamirs.hr.api.model.auth.AppAuthResource;
import pro.shushi.pamirs.hr.api.tmodel.AuthResourceTransient;
import pro.shushi.pamirs.hr.core.helper.ActionNameChecker;
import pro.shushi.pamirs.hr.core.helper.ModelDataHelper;
import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j;
import pro.shushi.pamirs.meta.api.session.PamirsSession;
import pro.shushi.pamirs.meta.common.exception.PamirsException;
import pro.shushi.pamirs.meta.domain.ModelData;
import pro.shushi.pamirs.meta.enmu.SystemSourceEnum;

import java.util.ArrayList;
import java.util.List;

/**
 * @author shushi
 */
@Slf4j
@Service
public class MetaOperateManager {

    public ServerAction buildServerAction(AppAuthResource authResource) {
        ServerAction action = new ServerAction();
        if (authResource.getResourceId() != null) {
            action.setId(authResource.getResourceId());
        }
        action.setDisplayName(authResource.getDisplayName());
        action.setSystemSource(SystemSourceEnum.UI);
        action.setName(authResource.getResUnique());
        // action.setFunctionDefinition(functionDefinition);
        action.setModel(AuthResourceTransient.MODEL_MODEL);
        action.setFun("construct");
        return createOrUpdateServerAction(action, Boolean.TRUE);
    }

    public ServerAction createOrUpdateServerAction(ServerAction serverAction, Boolean checkName) {
        //Step1、name符合规范
        ActionNameChecker.checkActionName(serverAction.getName());
        //Step2、不能重复
        ServerAction dbServerAction = new ServerAction().setModel(serverAction.getModel()).setName(serverAction.getName()).queryOne();
        if (dbServerAction != null && !dbServerAction.getId().equals(serverAction.getId())) {
            throw PamirsException.construct(HrSimpleExpEnum.ACTION_NAME_REPEAT_ERROR).errThrow();
        }
        Action dbAction = new Action().setModel(serverAction.getModel()).setName(serverAction.getName()).queryOne();
        if (dbAction != null) {
            throw PamirsException.construct(HrSimpleExpEnum.ACTION_NAME_REPEAT_ERROR).errThrow();
        }

        if (serverAction.getId() == null) {
            serverAction.setSys(false);
            serverAction.setActionType(ActionTypeEnum.SERVER);
            serverAction.setPriority(999);
            serverAction.construct();
        }
        serverAction.createOrUpdate();

        //写入modelData/刷新缓存 等
        _actionCreateOrUpdate(serverAction);
        return serverAction;
    }

    private void _actionCreateOrUpdate(Action action) {
        if (action == null || action.getId() == null) {
            return;
        }

        if (action instanceof ViewAction) {
            action = new ViewAction().queryById(action.getId());
        } else if (action instanceof ServerAction) {
            action = new ServerAction().queryById(action.getId());
        } else if (action instanceof UrlAction) {
            action = new UrlAction().queryById(action.getId());
        } else if (action instanceof ClientAction) {
            action = new ClientAction().queryById(action.getId());
        }

        //处理元数据注册
        ModelData modelData = ModelDataHelper.convert(action);
        modelData.construct();
        modelData.createOrUpdate();

        if (log.isInfoEnabled()) {
            log.info("开始写入动作缓存,id:{},model:{},name:{}", action.getId(), action.getModel(), action.getName());
        }

        Action finalAction = action;
        PamirsSession.getContext().putExtendCacheEntity(ActionCacheApi.class, (cacheApi) -> {
            cacheApi.put(finalAction.getSign(), finalAction);
        });
        PamirsSession.getContext().putExtendCacheEntity(ModelActionsCacheApi.class, (cacheApi) -> {
            String model = finalAction.getModel();
            //新建一个列表,全部处理完毕后再覆盖
            List<Action> cacheActions = cacheApi.get(model);
            List<Action> modelActions = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(cacheActions)) {
                modelActions.addAll(cacheActions);
            }
            modelActions.stream().filter(i -> finalAction.getSign().equals(i.getSign())).findFirst().ifPresent(modelActions::remove);
            modelActions.add(finalAction);

            cacheApi.put(model, modelActions);
        });

        //Spider.getDefaultExtension(ResetSessionCacheApi.class).resetMetadataCache(); //TODO
    }

    public void actionMetaDelHandler(Action action) {
        //处理元数据注册
        ModelData modelData = ModelDataHelper.convert(action);
        modelData.deleteByUnique();
        if (log.isInfoEnabled()) {
            log.info("开始删除动作缓存,id:{},model:{},name:{}", action.getId(), action.getModel(), action.getName());
        }

        Action finalAction = action;
        PamirsSession.getContext().putExtendCacheEntity(ActionCacheApi.class, (cacheApi) -> {
            cacheApi.remove(finalAction.getModel(), finalAction.getName());
        });

        PamirsSession.getContext().putExtendCacheEntity(ModelActionsCacheApi.class, (cacheApi) -> {
            String model = finalAction.getModel();
            //新建一个列表,全部处理完毕后再覆盖
            List<Action> cacheActions = cacheApi.get(model);
            List<Action> modelActions = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(cacheActions)) {
                modelActions.addAll(cacheActions);
            }
            modelActions.stream().filter(i -> finalAction.getSign().equals(i.getSign())).findFirst().ifPresent(modelActions::remove);
            modelActions.remove(finalAction);

            cacheApi.put(model, modelActions);
        });
    }
}
